import BaseObj from "./BaseObj";
import ICanvas from "./ICanvas";
import ObjContainer from "./ObjContainer";
import Time from "./Time";
import IhooksContainer from "./canvas_hooks/IHooksContainer";
import DefaultHooksContainer from "./canvas_hooks/hooks_containers/DefaultHooksContainer";
import Circle from "./shapes/Circle";
import TypeUtils from "./utils/TypeUtils";

export default class DefaultCanvas implements ICanvas{
    canvasEl:HTMLCanvasElement;
    ctx:CanvasRenderingContext2D;
    requestAnimationId:number|null
    hooks:IhooksContainer
    constructor(queryId:string){
        this.canvasEl = document.querySelector(queryId) as HTMLCanvasElement
        this.canvasEl.width = window.innerWidth
        this.canvasEl.height = window.innerHeight 
        this.ctx = this.canvasEl.getContext("2d") as CanvasRenderingContext2D
        window.addEventListener("resize",(ev:UIEvent)=>{
            this.canvasEl.width = window.innerWidth 
            this.canvasEl.height = window.innerHeight 
        })
        this.hooks = new DefaultHooksContainer()
        this.canvasEl.addEventListener("click",this.canvasClick)
    }

    canvasClick(e:MouseEvent){
        for(let obj of ObjContainer.container){
            if(obj instanceof Circle){
                if(obj.containPoint(e.clientX,e.clientY)){
                    console.log(`Circle ${obj.id} 被点击了`);
                    
                }
            }
        }
    }

    draw() {
        let nowTime = performance.now()
        Time.frameTime =  (nowTime- Time.preFrameStartTime)/1000
        Time.preFrameStartTime = nowTime
        this.beforeRender(this)//执行渲染前的钩子函数
        this.update()
        this.render()
        this.afterRender(this)//执行渲染后的钩子函数
        this.requestAnimationId= requestAnimationFrame(this.draw.bind(this))

    }
    beforeRender(canvas:ICanvas) {
        let container = (this.hooks as DefaultHooksContainer).container
        for(let hook of container){
            if( TypeUtils.instanceofIHooksRender(hook)){
                if(hook.canRender) hook.beforeRender(this)
            }
        }
    }
    afterRender(canvas:ICanvas) {
        let container = (this.hooks as DefaultHooksContainer).container
        for(let hook of container){
            if( TypeUtils.instanceofIHooksRender(hook)){
                if(hook.canRender) hook.afterRender(this)
            }
        }
    }

    update() {
        ObjContainer.container.forEach((obj)=>{
            try{
                obj.update()
            }catch(e){
                console.log(e);
            }
        })
    }



    render(){
        //TODO 对需要画的对象进行前置操作，过滤，筛选等 
        this.ctx.clearRect(0,0,this.canvasEl.width,this.canvasEl.height)
        ObjContainer.container.forEach((obj)=>{
            try{
                this.ctx.save()
                this.ctx.beginPath()
                obj.draw(this.ctx)
            }catch(e){
                console.log(e);
            }finally{
                this.ctx.restore()   
                this.ctx.closePath()
            }
        })
    }

}

